package com.heima.controller.doctor;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.heima.Result;
import com.heima.config.JWTConfig;
import com.heima.domain.dto.DoctorDTO;
import com.heima.domain.po.Doctor;
import com.heima.domain.vo.DoctorVO;
import com.heima.exception.DIYException;
import com.heima.service.IDoctorService;
import com.heima.util.JwtUtil;
import com.heima.util.RegexUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import com.heima.util.RedisUtil;

/**
 * <p>
 * 医生信息表 前端控制器
 * </p>
 *
 * @author author
 * @since 2025-07-24
 */
@Tag(name = "医生相关接口")
@RestController
@RequestMapping("/doctor")
public class DoctorController {
    @Autowired
    private IDoctorService doctorService;
    @Autowired
    private JWTConfig jwtConfig;
    @Autowired
    private RedisUtil redisUtil;

    private static final String PreKey="doctor:code:";
    @Operation(summary = "医生登录")
    @PostMapping("/login")
    public Result login(@RequestBody DoctorDTO doctorDTO) {
        String phone = doctorDTO.getPhone();
        String password = doctorDTO.getPassword();
        String account = doctorDTO.getAccount();
        if((StrUtil.isBlank(phone) &&   StrUtil.isBlank(account)) ||StrUtil.isBlank(password)) {
            throw new DIYException("手机号、密码或账号不能为空");
        }
        if(password.length() < 6 || password.length() > 16) {
            throw new DIYException("密码长度必须在6到16个字符之间");
        }
        Doctor doctor = doctorService.lambdaQuery()
                .eq(StrUtil.isNotBlank(phone), Doctor::getPhone, phone)
                .eq(StrUtil.isNotBlank(account), Doctor::getAccount, account)
                .one();
        if(doctor == null) throw new DIYException("用户不存在");
        if(!doctor.getPassword().equals(password)) throw new DIYException("密码错误");
        DoctorVO doctorVO = BeanUtil.copyProperties(doctor, DoctorVO.class);
        Map<String, Object> claims =new HashMap<>();
        claims.put("doctorId", doctor.getId());
        claims.put("account", account);
        String token= JwtUtil.getToken(claims, jwtConfig.getDockerTtl(), jwtConfig.getDockerSecretKey());
        doctorVO.setToken(token);
        return Result.success(doctorVO);
    }

    @Operation(summary = "医生注册")
    @PostMapping("/register")
    public Result register(@RequestBody DoctorDTO doctorDTO) {
        String phone = doctorDTO.getPhone();
        String password = doctorDTO.getPassword();
        if(StrUtil.isBlank(phone)||StrUtil.isBlank(password)) {
           throw new DIYException("手机号或密码不能为空");
        }
        if(password.length() < 6 || password.length() > 16) {
            throw new DIYException("密码长度必须在6到16个字符之间");
        }
        if(RegexUtils.isPhoneInvalid(phone)) {
            throw new DIYException("手机号格式不正确");
        }
        // 获取医生信息
        Doctor doctor = doctorService.lambdaQuery()
                .eq(Doctor::getPhone, phone).one();
        if(doctor != null) throw new DIYException("手机号已被注册");
        doctor = new Doctor();
        BeanUtils.copyProperties(doctorDTO, doctor);
        if(StrUtil.isBlank(doctor.getNickname())) {
            // 生成UUID
            UUID uuid = UUID.randomUUID();
            // 转换为字符串并去除横杠
            String uuidWithoutHyphens = uuid.toString().replace("-", "");
            // 截取前8个字符作为昵称
            String nickname = uuidWithoutHyphens.substring(0, 8);
            doctor.setNickname("医生_" + nickname);
        }
        doctor.setCreateTime(LocalDateTime.now());
        doctor.setUpdateTime(LocalDateTime.now());
        doctorService.save(doctor);
        return Result.success();
    }


    @Operation(summary = "获取手机验证码")
    @PostMapping("/getCode")
    public Result getCode(@RequestBody DoctorDTO doctorDTO) {
        String phone = doctorDTO.getPhone();
        if (StrUtil.isBlank(phone)) {
            throw new DIYException("手机号不能为空");
        }
        if (RegexUtils.isPhoneInvalid(phone)) {
            throw new DIYException("手机号格式不正确");
        }
        // 生成验证码
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String code = uuid.substring(0, 6); // 取前 6 位
        // 保存验证码到缓存
        boolean isSaved = redisUtil.setWithExpiration(PreKey + phone, code, 2 * 60);// 设置2分钟过期
        if (!isSaved) {
            throw new DIYException("验证码发送过于频繁，请稍后再试");
        }
        return Result.success(code);
    }
    @Operation(summary = "手机验证码登录")
    @PostMapping("/loginByPhone")
    public Result loginByPhone(@RequestBody DoctorDTO doctorDTO) {
        String phone = doctorDTO.getPhone();
        String code = doctorDTO.getCode();
        if(StrUtil.isBlank(phone) || StrUtil.isBlank(code)) {
            throw new DIYException("手机号或验证码不能为空");
        }
        if(RegexUtils.isPhoneInvalid(phone)) {
            throw new DIYException("手机号格式不正确");
        }
        // 验证码校验
        if(!redisUtil.exists(PreKey + phone)) {
            throw new DIYException("验证码已过期，请重新获取");
        }
        if(!redisUtil.get(PreKey + phone).equals(code)) {
            throw new DIYException("验证码错误");
        }
        // 获取医生信息
        Doctor doctor = doctorService.lambdaQuery()
                .eq(Doctor::getPhone, phone).one();
        if(doctor == null) throw new DIYException("用户不存在，请先用手机号注册");
        DoctorVO doctorVO = BeanUtil.copyProperties(doctor, DoctorVO.class);
        Map<String, Object> claims =new HashMap<>();
        claims.put("doctorId", doctor.getId());
        claims.put("account", doctor.getAccount());
        String token= JwtUtil.getToken(claims, jwtConfig.getDockerTtl(), jwtConfig.getDockerSecretKey());
        doctorVO.setToken(token);
        return Result.success(doctorVO);
    }

}
